bits 16

org 0x500

jmp main

;=====================================
;Code-Includes
;=====================================
%include "stdio.inc" 	;i/o routines
%include "gdt.inc"	;gdt routines
%include "A20.inc"	;A20 enabling routines
%include "Fat12.inc"	;Fat12 routines
%include "common.inc"
;=====================================
;Data-Section
;=====================================


loadMsg db "Preparing to load operating system...", 0x0D, 0x0A, 0x00
msgFailure db "Error occured...", 0x0D, 0x0A, 0x00

;=============================================
;STAGE2 ENTRY POINT
;
;-Store BIOS information
;-Load Kernel
;-Install GDT; go into protected mode (pmode)
;-Jump to Stage3
;=============================================


main:

	;=====================================
	;	Setup segments and stack
	;=====================================

	cli
	xor	ax, ax
	mov	ds, ax
	mov	es, ax
	mov	ax, 0x9000	; stack begins at 0x9000
	mov 	ss, ax
	mov	sp, 0xFFFF	; stack ends at 0xffff
	sti

	;=====================================
	;	Print loading msg
	;=====================================


	mov	si, loadMsg
	call	Puts16		;calls Puts16 in stdio.inc

	;=====================================
	;	Install our GDT
	;=====================================


	call InstallGDT		;call InstallGDT in gdt.inc

	;=====================================
	;	Enable A20 Address Line
	;=====================================

	call EnableA20_KKbrd_Out	;call EnableA20_KKbrd_Out in A20.inc

	;=====================================
	;	Initiate pmode
	;=====================================
	
	call	LoadRoot		;load root directory table

	mov	ebx, 0			;BX:BP points to buffer to load to
   	mov	ebp, IMAGE_RMODE_BASE
	mov	Esi, ImageName		;our file to load
	call	LoadFile		;load our file
	MOV	dword [ImageSize], ecx	;size of kernel
	cmp	ax, 0			;test for success
	je	EnterStage3		;load Stage3
	mov	si, msgFailure		;print error
	call	Puts16
	mov	ah, 0
	int     0x16                    ;await keypress
	int     0x19                    ;warm boot computer
	cli
	hlt

EnterStage3:

	cli
	mov 	eax, cr0
	or	eax, 1
	mov	cr0, eax
	
	jmp 	08h:Stage3
	
		
;=============================================
;STAGE3 ENTRY POINT
;=============================================


bits 32		;Now running in 32 bit!

BadImage db "*** FATAL: Invalid or corrupt kernel image. Halting system.", 0
Success  db "Success!"

Stage3:

	;=====================================
	;	Set Registers
	;=====================================
	
	mov	ax, 0x10	;set data segments to data selector
	mov	ds, ax	
	mov	es, ax
	mov	ss, ax
	mov	esp, 90000h 	;stack begins from 0x90000

	call	ClrScr32


CopyImage:		;Copy kernel to 1MB (0x10000)
			
  	mov	eax, dword [ImageSize]
  	movzx	ebx, word [bpbBytesPerSector]
  	mul	ebx
   	mov	ebx, 4
  	div	ebx
   	cld
   	mov    	esi, IMAGE_RMODE_BASE
   	mov	edi, IMAGE_PMODE_BASE
   	mov	ecx, eax
   	rep	movsd       ;copy image to its protected mode address

  	
	;=====================================
	;   Clear screen and Test Image	
	;=====================================
	

TestImage:
  	  mov    ebx, [IMAGE_PMODE_BASE+60]
  	  add    ebx, IMAGE_PMODE_BASE    ; ebx now points to file sig (PE00)
  	  mov    esi, ebx
  	  mov    edi, ImageSig
  	  cmpsw
  	  je     EXECUTE
  	  mov	ebx, BadImage
  	  call	Puts32
  	  cli
  	  hlt

ImageSig db 'PE'

EXECUTE:

	;---------------------------------------;
	;   Execute Kernel
	;---------------------------------------;

 	; parse the programs header info structures to get its entry point
	; ebx points to _IMAGE_FILE_HEADER

	add		ebx, 24
	mov		eax, [ebx]			; _IMAGE_FILE_HEADER is 20 bytes + size of sig (4 bytes)
	add		ebx, 20-4			; address of entry point
	mov		ebp, dword [ebx]		; get entry point offset in code section	
	add		ebx, 12				; image base is offset 8 bytes from entry point
	mov		eax, dword [ebx]		; add image base
	add		ebp, eax
	mov	ebx, Success
  	call	Puts32
	cli

	call		ebp               	      ; Execute Kernel
	
    	cli
	hlt


;-- header information format for PE files -------------------

;typedef struct _IMAGE_DOS_HEADER {  // DOS .EXE header
;    USHORT e_magic;         // Magic number (Should be MZ
;    USHORT e_cblp;          // Bytes on last page of file
;    USHORT e_cp;            // Pages in file
;    USHORT e_crlc;          // Relocations
;    USHORT e_cparhdr;       // Size of header in paragraphs
;    USHORT e_minalloc;      // Minimum extra paragraphs needed
;    USHORT e_maxalloc;      // Maximum extra paragraphs needed
;    USHORT e_ss;            // Initial (relative) SS value
;    USHORT e_sp;            // Initial SP value
;    USHORT e_csum;          // Checksum
;    USHORT e_ip;            // Initial IP value
;    USHORT e_cs;            // Initial (relative) CS value
;    USHORT e_lfarlc;        // File address of relocation table
;    USHORT e_ovno;          // Overlay number
;    USHORT e_res[4];        // Reserved words
;    USHORT e_oemid;         // OEM identifier (for e_oeminfo)
;    USHORT e_oeminfo;       // OEM information; e_oemid specific
;    USHORT e_res2[10];      // Reserved words
;    LONG   e_lfanew;        // File address of new exe header
;  } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;



;typedef struct _IMAGE_FILE_HEADER {
;    USHORT  Machine;
;    USHORT  NumberOfSections;
;    ULONG   TimeDateStamp;
;    ULONG   PointerToSymbolTable;
;    ULONG   NumberOfSymbols;
;    USHORT  SizeOfOptionalHeader;
;    USHORT  Characteristics;
;} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

;struct _IMAGE_OPTIONAL_HEADER {
;    //
;    // Standard fields.
;    //
;    USHORT  Magic;
;    UCHAR   MajorLinkerVersion;
;    UCHAR   MinorLinkerVersion;
;    ULONG   SizeOfCode;
;    ULONG   SizeOfInitializedData;
;    ULONG   SizeOfUninitializedData;
;    ULONG   AddressOfEntryPoint;			<< IMPORTANT!
;    ULONG   BaseOfCode;
;    ULONG   BaseOfData;
;    //
;    // NT additional fields.
;    //
;    ULONG   ImageBase;
;    ULONG   SectionAlignment;
;    ULONG   FileAlignment;
;    USHORT  MajorOperatingSystemVersion;
;    USHORT  MinorOperatingSystemVersion;
;    USHORT  MajorImageVersion;
;    USHORT  MinorImageVersion;
;    USHORT  MajorSubsystemVersion;
;    USHORT  MinorSubsystemVersion;
;    ULONG   Reserved1;
;    ULONG   SizeOfImage;
;    ULONG   SizeOfHeaders;
;    ULONG   CheckSum;
;    USHORT  Subsystem;
;    USHORT  DllCharacteristics;
;    ULONG   SizeOfStackReserve;
;    ULONG   SizeOfStackCommit;
;    ULONG   SizeOfHeapReserve;
;    ULONG   SizeOfHeapCommit;
;    ULONG   LoaderFlags;
;    ULONG   NumberOfRvaAndSizes;
;    IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
;} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;

